iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
1
Modern Web

PHP框架-Symfony4 + api platform 系列 第 17

Day#17 分頁設定Pagination 及 Attributes 裡一些哩哩摳摳的設定=͟͟͞͞( •̀д•́)

  • 分享至 

  • xImage
  •  

假設我今天透過api的集合GET撈出來有幾萬筆十萬筆資料,總不可能全部都讓它們擠在同一個頁面上吧,
這樣除了Loading會太大外,使用者要看也不方便,
先前在提集合GET的時候,應該有看到一個預設的搜尋條件叫page,
這個搜尋條件是來決定我今天所要搜尋的頁數是第幾頁


那我們要怎麼決定我一頁要顯示幾筆呢!?
一般來說,若我們沒有特別去設定,預設是一頁30筆,
但我們可以透過attributes裡的pagination相關的設定來做調整

1.調整一頁所顯示的筆數 => pagination_items_per_page,等於後面放的是筆數

 * @ApiResource(
 *     collectionOperations={"get","post"},
 *     itemOperations={
 *          "get"={
 *              "normalization_context"={"groups"={"test:read", "test:item:get"}}
 *          },
 *          "put" = {
 *              "denormalization_context"={"groups"={"test:item:put"}}
 *          },
 *          "delete"
 *      },
 *     normalizationContext={"groups"={"test:read"},"enable_max_depth"="true","skip_null_values" = false},
 *     denormalizationContext={"groups"={"test:write"},"disable_type_enforcement"=true},
 *     attributes={"pagination_items_per_page"=10}
 * )

2.是否提供頁數搜尋 !? pagination_client_enabled,若值為true即可搜尋

 * @ApiResource(
 *     collectionOperations={"get","post"},
 *     itemOperations={
 *          "get"={
 *              "normalization_context"={"groups"={"test:read", "test:item:get"}}
 *          },
 *          "put" = {
 *              "denormalization_context"={"groups"={"test:item:put"}}
 *          },
 *          "delete"
 *      },
 *     normalizationContext={"groups"={"test:read"},"enable_max_depth"="true","skip_null_values" = false},
 *     denormalizationContext={"groups"={"test:write"},"disable_type_enforcement"=true},
 *     attributes={"pagination_items_per_page"=10,"pagination_client_enabled" = true}
 * )

attributes這個屬性一定要放在Api Resource裡,且裡面的設定,必須以逗號分開

上述舉例是一頁顯示10筆,可提供頁數查詢

一般來說,資料如果沒有特別的排序(Order),都是按照id的順序來排,
但如果我今天想用特定欄位來進行排序,對...
我們要嘛是自己提供Filter,要嘛是....更簡單的!!? 設定~ ,
這時候大家心裡一定有疑問,既然有設定,幹嘛還要自己寫Filter,
因為有時候我們要排序的資料,除了原來的搜尋條件,也可能是要透過別的條件過濾出來的

設定比較簡單,那我們就講設定吧? 阿 ...不是 ,是因為一般排序用設定就好了

在Attributes裡加上order

 * @ApiResource(
 *     collectionOperations={
 *          "get"= {
 *              "security"="is_granted('ROLE_MA01_read') or is_granted('ROLE_MM01_read') and is_granted('VIEW',object)"
 *          },
 *          "post" = {
 *              "security_post_denormalize" = "is_granted('ROLE_MA01_create') or is_granted('ROLE_MM01_create') ",
 *              "validation_groups" = {Megp::class, "validationGroups"}
 *          }
 *      },
 *     itemOperations={
 *          "get" = {
 *              "security"="is_granted('ROLE_MA01_read') or is_granted('ROLE_MM01_read') and is_granted('VIEW',object)"
 *          },
 *          "put" = {
 *              "security_post_denormalize" = "(is_granted('ROLE_MA01_update') or is_granted('ROLE_MM01_update') and is_granted('EDIT', previous_object)) and is_granted('VERIFY', object)"
 *          },
 *          "patch" = {
 *              "security_post_denormalize" = "is_granted('ROLE_MA01_update') or is_granted('ROLE_MM01_update') and is_granted('EDIT', previous_object)"
 *          },
 *          "delete" = {
 *              "security_post_denormalize" = "is_granted('ROLE_MA01_delete') or is_granted('ROLE_MM01_delete') and is_granted('EDIT', previous_object)"
 *          },
 *          "put_reissue"={
 *              "method"="put",
 *              "route_name"="create_megp_reissue_update",
 *              "security" = "is_granted('ROLE_MA01_update')"
 *          },
 *          "put_mover"={
 *              "method"="put",
 *              "route_name"="create_megp_mover_update",
 *              "security" = "is_granted('ROLE_MA01_update')"
 *          },
 *     },
 *     normalizationContext={"groups"={"megp:read"},"enable_max_depth"="true","skip_null_values" = false},
 *     denormalizationContext={"groups"={"megp:write"},"disable_type_enforcement"=true},
 *     attributes={"pagination_items_per_page"=10,"pagination_client_enabled" = true,"order"={"birthDay": "ASC"}}
 * )

order的第一個參數是欄位,第二個是正序(ASC)或倒序(DESC)

這裡額外講一個不是在Api platform裡設定的東西 => 唯一值

如果今天我想讓我的email是唯一的值,也就是說當今天資料已經存在123@test.gmail了,
另一個人要輸入123@test.gmail,就會被我們所設定的唯一值擋掉

 *  @UniqueEntity(
 *     fields={"email"},
 *     message="Email已使用!!",
 *  )
使用uniqueEntity 記得要import Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

唯一值的欄位,可以用兩個做設定,比如姓名搭配email為唯一值,那這樣檢查就是姓名跟email一組,有重複的才會被擋下來

以上,講完還算簡單的pagination,排序,和唯一值設定,
雖然說簡單,但是其實pagination也有難的地方,因為如果我們是用設定的方式,只能在預設的集合get做使用,
假設我們今天自己寫了一個集合Get的API , 阿我們沒有東西可以設定頁數了怎麼辦,
難道我就只能讓撈出來的一大坨資料全部顯示出來嗎....?
當然不是,其實有一個解法,就是在資料庫Select的時候,去做換頁的動作

下一篇,會來介紹如何建立一個最陽春最簡單的customize get api ,
後續會來談談小菜鳥本人一直以為沒有設定就達不到的換頁吧!!! 前一陣子才在跟同事討論,到底自己寫換頁搭API 可不可行 ..然後兩個苦惱工程師就在那試了一個小時,終於...皇天不負苦心人,被我們給試出來了。・゚・(つд`゚)・゚・


上一篇
Day#16 自己要的東西自己生!! 客製化Filter
下一篇
Day#18 自己產出一個Get API - Customize Get API
系列文
PHP框架-Symfony4 + api platform 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言